package com.winshare.saleAssistant.service.impl;

import com.winshare.saleAssistant.dao.MenuRoleMapper;
import com.winshare.saleAssistant.dao.RoleMapper;
import com.winshare.saleAssistant.dao.StaffRoleMapper;
import com.winshare.saleAssistant.domain.entity.MenuDO;
import com.winshare.saleAssistant.domain.entity.RoleDO;
import com.winshare.saleAssistant.domain.entity.RoleMenuDO;
import com.winshare.saleAssistant.domain.entity.RoleStaffDO;
import com.winshare.saleAssistant.domain.query.RoleQuery;
import com.winshare.saleAssistant.domain.dto.req.*;
import com.winshare.saleAssistant.domain.dto.resp.RoleRespDTO;
import com.winshare.saleAssistant.exception.BusinessException;
import com.winshare.saleAssistant.mapper.RoleMapStruct;
import com.winshare.saleAssistant.service.RoleService;
import com.winshare.saleAssistant.util.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    private final RoleMapper roleMapper;

    private final MenuRoleMapper menuRoleMapper;

    private final StaffRoleMapper staffRoleMapper;

    public RoleServiceImpl(RoleMapper roleMapper, MenuRoleMapper menuRoleMapper, StaffRoleMapper staffRoleMapper) {
        this.roleMapper = roleMapper;
        this.menuRoleMapper = menuRoleMapper;
        this.staffRoleMapper = staffRoleMapper;
    }

    @Override
    public void save(RoleCreateDTO roleCreateDTO) {
        RoleDO roleDO = RoleMapStruct.INSTANCE.fromRoleCreateDTO(roleCreateDTO);
        if(checkRoleExist(roleDO)) {
            throw new BusinessException("当前角色已经存在");
        }
        roleMapper.saveRole(roleDO);
        RoleDO roleInSql = roleMapper.queryByRole(roleDO);
        List<MenuDO> menuDOList = roleDO.getMenuList();
        if(!CollectionUtils.isEmpty(menuDOList)) {
            List<RoleMenuDO> roleMenuDOList = menuDOList.stream().map(item -> {
                RoleMenuDO roleMenuDO = new RoleMenuDO();
                roleMenuDO.setMenuId(item.getId());
                roleMenuDO.setRoleId(roleInSql.getId());
                return roleMenuDO;
            }).collect(Collectors.toList());
            menuRoleMapper.batchInsertRoleMenu(roleMenuDOList);
        }
    }

    @Override
    public void update(RoleUpdateDTO roleUpdateDTO) {
        RoleDO roleDO = RoleMapStruct.INSTANCE.fromRoleUpdateDTO(roleUpdateDTO);
        if(roleDO.getRoleName().equals("admin") || roleDO.getId() == 1) {
            throw new BusinessException("当前角色为超级管理员的角色，不能随意修改。");
        }
        if(checkRoleExist(roleDO)) {
            throw new BusinessException("当前角色已经存在");
        }
        roleMapper.updateRole(roleDO);
        menuRoleMapper.deleteByRole(roleDO);
        List<MenuDO> menuDOList = roleDO.getMenuList();
        if(!CollectionUtils.isEmpty(menuDOList)) {
            List<RoleMenuDO> roleMenuDOList = menuDOList.stream().map(item -> {
                RoleMenuDO roleMenuDO = new RoleMenuDO();
                roleMenuDO.setMenuId(item.getId());
                roleMenuDO.setRoleId(roleDO.getId());
                return roleMenuDO;
            }).collect(Collectors.toList());
            menuRoleMapper.batchInsertRoleMenu(roleMenuDOList);
        }
    }

    @Override
    public void delete(RoleDeleteDTO roleDeleteDTO) {
        RoleDO roleDO = RoleMapStruct.INSTANCE.fromRoleDeleteDTO(roleDeleteDTO);
        if( roleDO.getId() == 1) {
            throw new BusinessException("当前角色为超级管理员的角色，不能随意删除。");
        }
        if(checkExistMenu(roleDO)) {
            throw new BusinessException("该角色下面还存在菜单,故不能删除!");
        }
        if(checkExistPerson(roleDO)) {
            throw new BusinessException("该角色下面还存在员工,故不能删除!");
        }
        roleMapper.deleteRole(roleDO);
        menuRoleMapper.deleteByRole(roleDO);
    }

    @Override
    public Page<RoleRespDTO> getRoleList(RoleQueryDTO roleQueryDTO) {
        RoleQuery roleQuery = RoleMapStruct.INSTANCE.fromRoleQueryDTO(roleQueryDTO);
        roleQuery.setOffsetIndex(roleQueryDTO.getOffsetIndex());
        int totalCount = roleMapper.queryRoleCount(roleQuery);
        Integer pageIndex = roleQueryDTO.getPageIndex();
        Integer pageSize = roleQueryDTO.getPageSize();
        if(0 == totalCount) {
            return new Page<>(pageIndex,pageSize,totalCount,new ArrayList<>());
        }
        List<RoleDO> roleDOList = roleMapper.findRoleListByConditions(roleQuery);
        roleDOList.forEach(item -> {
            item.setAccountCount(staffRoleMapper.countStaffByRole(item));
        });
        List<RoleRespDTO> roleRespDTOList =
                RoleMapStruct.INSTANCE.toRoleRespDTOList(roleDOList);
        return new Page<>(pageIndex,pageSize,totalCount,roleRespDTOList);
    }

    @Override
    public void setPersonList(RoleSettingPeronDTO roleSettingPeronDTO) {
        RoleDO roleDO = RoleMapStruct.INSTANCE.fromRoleSettingPersonDTO(roleSettingPeronDTO);
        RoleDO roleInSql = roleMapper.queryByRole(roleDO);
        if(null == roleInSql) {
            throw new BusinessException("当前角色不存在！");
        }
        List<StaffDTO> staffDTOList = roleSettingPeronDTO.getStaffList();
        if(!CollectionUtils.isEmpty(staffDTOList)) {
            List<RoleStaffDO> roleStaffDOList = staffDTOList.stream().map(item ->{
                RoleStaffDO roleStaffDO = new RoleStaffDO();
                roleStaffDO.setRoleId(roleInSql.getId());
                roleStaffDO.setStaffId(item.getId());
                return roleStaffDO;
            }).collect(Collectors.toList());
            staffRoleMapper.batchInsertStaffRole(roleStaffDOList);
        }
    }

    @Override
    public RoleRespDTO getRoleDetail(BaseIdDTO baseIdDTO) {
        RoleDO roleDO = RoleMapStruct.INSTANCE.fromBaseIdDTO(baseIdDTO);
        RoleDO roleDOInSql = roleMapper.getRole(roleDO);
        if(null == roleDOInSql) {
            throw new BusinessException("当前角色不存在！");
        }
        RoleRespDTO roleRespDTO = RoleMapStruct.INSTANCE.toRoleRespDTO(roleDOInSql);
        return roleRespDTO;
    }

    private boolean checkExistMenu(RoleDO roleDO) {
        return menuRoleMapper.countMenuByRole(roleDO) > 0;
    }
    private boolean checkExistPerson(RoleDO roleDO) {
        return staffRoleMapper.countPersonByRole(roleDO) > 0;
    }

    private boolean checkRoleExist(RoleDO roleDO) {
        return roleMapper.countByRoleName(roleDO) > 0 ;
    }
}
